package com.pi.shisan.component.impl;

import com.pi.shisan.common.NumberUtil;
import com.pi.shisan.component.AnimationComponent;
import com.pi.shisan.component.util.AnimationThread;
import com.pi.shisan.component.util.ComponentThread;
import com.pi.shisan.component.util.FastIntList;
import com.pi.shisan.component.util.SharedSource;
import com.pi.shisan.util.DefaultFont8x8;
import com.pi.shisan.util.spipoint.DataWriter;
import com.pi.shisan.util.spipoint.MultipleXyToSpiConverter;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalTime;

import static com.pi.shisan.component.util.SharedMethod.drawPoints;

/**
 * 时间组件
 */
@Slf4j
public class LocalTimeComponent extends AnimationComponent {

    /**
     * 冒号缓存
     */
    private int[] colon = DefaultFont8x8.getPointsAsXy(DefaultFont8x8.SIGN_SMALL_COLON);

    /**
     * 上一次绘制过的所有点保存
     */
    private final FastIntList lastAllPoints = new FastIntList();

    /**
     * 组件内容坐标X
     */
    private int fromX;
    /**
     * 组件内容坐标Y
     */
    private int fromY;

    private boolean showSeconds;

    public LocalTimeComponent(MultipleXyToSpiConverter spi, DataWriter dataWriter) {
        super(spi, dataWriter);
    }

    public LocalTimeComponent(MultipleXyToSpiConverter spi, DataWriter dataWriter, boolean showSeconds) {
        super(spi, dataWriter);
        this.showSeconds = showSeconds;
    }


    @Override
    public void refresh() {
        ComponentThread.execute(()->{
            try {
                doRefresh();
            } catch (Exception e) {
                log.error("时间组件刷新失败：",e);
            }
        });
    }

    private void doRefresh() {
        LocalTime now = LocalTime.now();
        int hour = now.getHour();
        int minute = now.getMinute();
        int seconds = now.getSecond();

        int x = fromX;
        int y = fromY;
        lastAllPoints.forEach(spi::delete);
        //修复这个家伙可能带来的内存溢出问题（之前都没做过clear...）
        lastAllPoints.clear();
        int maxY = Short.MIN_VALUE;
        for (int i = 1; i >= 0; i--) {
            int maxX = Integer.MIN_VALUE;
            int[] numPoints = SharedSource.getFromNumCache(NumberUtil.getSimpleNum(hour, i));
            int max = drawPoints(numPoints,startX, startY, x, y, maxX,maxY, width, height, spi, lastAllPoints);
            maxX = NumberUtil.toX(max);
            maxY = NumberUtil.toY(max);
            x += maxX + 2;
        }
        if ((seconds & 1) == 1) {
            drawPoints(colon,startX, startY, x, y, Integer.MIN_VALUE,maxY, width, height, spi, lastAllPoints);
        }
        x += 1 + 1;
        for (int i = 1; i >= 0; i--) {
            int maxX = Integer.MIN_VALUE;
            int[] numPoints = SharedSource.getFromNumCache(NumberUtil.getSimpleNum(minute, i));
            int max = drawPoints(numPoints,startX, startY, x, y, maxX,maxY, width, height, spi, lastAllPoints);
            maxX = NumberUtil.toX(max);
            maxY = NumberUtil.toY(max);
            x += maxX + 2;
        }
        if (showSeconds) {
            if ((seconds & 1) == 1) {
                drawPoints(colon,startX, startY, x, y, Integer.MIN_VALUE,maxY, width, height, spi, lastAllPoints);
            }
            x += 1 + 1;
            for (int i = 1; i >= 0; i--) {
                int maxX = Integer.MIN_VALUE;
                int[] numPoints = SharedSource.getFromNumCache(NumberUtil.getSimpleNum(seconds, i));
                int max = drawPoints(numPoints,startX, startY, x, y, maxX,maxY, width, height, spi, lastAllPoints);
                maxX = NumberUtil.toX(max);
                maxY = NumberUtil.toY(max);
                x += maxX + 2;
            }
        }

        flushData();
    }

    @Override
    protected AnimationThread prepareAnimation() {
        return new LocalTimeAnimationThread(this);
    }

    static class LocalTimeAnimationThread extends AnimationThread {

        private LocalTimeComponent localTimeComponent;

        public LocalTimeAnimationThread(LocalTimeComponent localTimeComponent) {
            this.localTimeComponent = localTimeComponent;
            setName("local-time-animation");
        }

        @Override
        public void doRun() {
            if (localTimeComponent.width > 0) {
                localTimeComponent.fromX = localTimeComponent.width;
            }
            while (!destroy) {
                if (localTimeComponent.fromX > 0) {
                    localTimeComponent.fromX --;
                } else if (localTimeComponent.fromX < 0) {
                    localTimeComponent.fromX ++;
                }
                localTimeComponent.refresh();
                if (localTimeComponent.fromX != 0) {
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                    }
                } else {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                }
            }
        }
    }
}
